﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lm.Common.ExtensionMethods
{
    public static class NetworkStreamExt
    {
        /// <summary>
        /// 在把数据写入流之前，先写入一个4字节的int值，用该值描述要写入数据的长度。
        /// 此方法与ReadBlock配对使用
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="buf"></param>
        public static void WriteBlock(this System.Net.Sockets.NetworkStream stream, byte[] buf)
        {
            stream.Write(BitConverter.GetBytes(buf.Length), 0, 4);
            stream.Write(buf, 0, buf.Length);
            stream.Flush();
        }

        /// <summary>
        /// 在从流中读取数据之前，先取得4个字节的int值，以确定实际数据的长度，
        /// 此方法与WriteBlock配对使用
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static byte[] ReadBlock(this System.Net.Sockets.NetworkStream stream)
        {
            var lengthBuf = stream.Read(4);
            if (lengthBuf.Length != 4)
            { throw new System.IO.IOException("读取数据长度出错"); }
            var length = BitConverter.ToInt32(lengthBuf, 0);
            var dataBuf = stream.Read(length);
            if (dataBuf.Length != length)
            { throw new System.IO.IOException("读取数据出错"); }
            return dataBuf;
        }

        /// <summary>
        /// 以WriteBlock方法为基础，向流中写字符串，与ReadStringBlock方法配对使用。
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="str"></param>
        public static void WriteStringBlock(this System.Net.Sockets.NetworkStream stream, string str)
        {
            stream.WriteBlock(Encoding.UTF8.GetBytes(str));
        }

        /// <summary>
        /// 以ReadBlock方法为基础，从流中读取字符串，与WriteStringBlock配对使用。
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static string ReadStringBlok(this System.Net.Sockets.NetworkStream stream)
        {
            return Encoding.UTF8.GetString(stream.ReadBlock());
        }
    }
}
